Writing and Managing `pf.conf`

The `pf.conf` file is the heart of OpenBSD’s `pf` (Packet Filter) firewall. It defines all the rules, options, and configurations for the firewall. This tutorial provides an in-depth guide to writing, organizing, and managing `pf.conf` effectively, with examples and best practices.

Overview of `pf.conf`

The `pf.conf` file is typically located at `/etc/pf.conf`. It is a plain text file that contains the rules and settings for the `pf` firewall. The file is divided into several sections:

  • Macros: Variables for simplifying and reusing values.
  • Tables: Dynamic lists of IP addresses or networks.
  • Options: Global settings for `pf` behavior.
  • Normalization: Rules for normalizing packets.
  • Queueing: Traffic shaping and prioritization rules.
  • Filtering Rules: Rules for allowing or blocking traffic.
  • NAT and Redirection: Rules for Network Address Translation and port forwarding.

Basic Structure of `pf.conf`

Here’s a basic template for a `pf.conf` file:


# Macros
ext_if = "em0"  # External interface
int_if = "em1"  # Internal interface
local_net = "192.168.1.0/24"

# Tables
table  persist

# Options
set skip on lo  # Skip filtering on the loopback interface
set block-policy drop  # Drop packets silently
set loginterface $ext_if  # Log traffic on the external interface

# Normalization
scrub in on $ext_if all fragment reassemble

# NAT
nat on $ext_if from $local_net to any -> ($ext_if)

# Filtering Rules
block all
pass in on $int_if from $local_net to any keep state
pass out on $ext_if proto tcp to port 80 keep state
block in quick from 

Explanation

  • Macros: Simplify the configuration by defining variables for interfaces and networks.
  • Tables: Use dynamic lists for managing IP addresses efficiently.
  • Options: Configure global settings for `pf` behavior.
  • Normalization: Ensure packets are well-formed and reassemble fragments.
  • NAT: Enable NAT for traffic from the internal network to the external interface.
  • Filtering Rules: Define rules for blocking or allowing traffic.

Writing Rules in `pf.conf`

Rules in `pf.conf` are written in a specific format. Here’s a breakdown of the key components:

1. Block and Pass Rules

These rules determine whether traffic is allowed or blocked:


# Block all traffic by default
block all

# Allow incoming SSH traffic
pass in on $ext_if proto tcp to port 22 keep state

2. NAT Rules

NAT rules translate private IP addresses to public IP addresses:


# NAT for internal network
nat on $ext_if from $local_net to any -> ($ext_if)

3. Redirection Rules

Redirect traffic to internal servers:


# Redirect HTTP traffic to an internal web server
rdr on $ext_if proto tcp to port 80 -> 192.168.1.100 port 80

4. Logging Rules

Log specific traffic for monitoring and troubleshooting:


# Log incoming SSH traffic
pass in log on $ext_if proto tcp to port 22 keep state

5. Quick Rules

Quick rules are evaluated immediately and override subsequent rules:


# Block traffic from a specific IP immediately
block in quick from 192.168.1.200

Managing `pf.conf`

Once you’ve written your `pf.conf` file, you need to load and manage it using `pfctl`:

1. Enabling and Reloading `pf`


# Enable pf
pfctl -e

# Load the configuration file
pfctl -f /etc/pf.conf

2. Testing the Configuration

Always test your configuration before applying it:


# Test the syntax of pf.conf
pfctl -nf /etc/pf.conf

3. Viewing Active Rules

Check the currently loaded rules:


pfctl -sr

4. Monitoring Traffic

Use `tcpdump` to monitor traffic in real-time:


tcpdump -n -e -ttt -i pflog0

Best Practices for Managing `pf.conf`

Follow these best practices to ensure your `pf.conf` file is effective and maintainable:

  • Comment Your Rules: Add comments to explain the purpose of each rule.
  • Group Related Rules: Organize rules by function (e.g., NAT, filtering, logging).
  • Use Macros and Tables: Simplify your configuration and make it easier to update.
  • Test Before Applying: Always test your configuration with `pfctl -nf` before reloading it.
  • Enable Logging: Log critical rules to monitor traffic and troubleshoot issues.
  • Backup Configurations: Keep backups of your `pf.conf` file to recover from mistakes or failures.

Advanced Techniques

Here are some advanced techniques for managing `pf.conf`:

1. Dynamic Tables

Use tables to manage large lists of IP addresses dynamically:


table  persist
block in quick from 

Add or remove IPs dynamically:


pfctl -t blocked_ips -T add 192.168.1.100
pfctl -t blocked_ips -T delete 192.168.1.100

2. Anchors

Use anchors to modularize your configuration:


anchor "webserver"
load anchor "webserver" from "/etc/pf.webserver.conf"

Conclusion

Writing and managing `pf.conf` is a critical skill for using OpenBSD’s `pf` firewall effectively. By understanding its structure, syntax, and best practices, you can create powerful and maintainable firewall configurations. In the next tutorial, we’ll explore advanced features of `pf`, including traffic shaping and high availability. Stay tuned!

 

 

Check out some other Bands on Bandcamp.com. Crazy Fingers (Vancouver 1991), Flying Butt Pliers, and Hammy Ham Hands.

Proudly powered by a Text Editor, an IDE, an SFTP client, some Internet searches, and more recently help from some AI.

2025 dispelled.ca end of file.